package com.mastercard.assets.web.util.to;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import com.mastercard.assets.MasterCardException;
import com.mastercard.assets.jpa.TblAlertaUsuario;
import com.mastercard.assets.jpa.TblCuenta;
import com.mastercard.assets.jpa.TblGanador;
import com.mastercard.assets.jpa.TblNivel;
import com.mastercard.assets.jpa.TblRole;
import com.mastercard.assets.jpa.TblTipoCuenta;
import com.mastercard.assets.jpa.TblTipoCuentaPaquete;
import com.mastercard.assets.jpa.TblUsuario;
import com.mastercard.assets.util.MCUtil;
import com.mastercard.assets.util.dao.MasterCardDAO;
import com.mastercard.assets.web.struts.forms.GenerarCampanaRegistrarForm;

public class UserLogin
	implements
		Serializable
{
	private Hashtable< String , Object > attributes = new Hashtable< String , Object >( ) ;
	
	private String messageError ;
	private String messageError2 ;
	private String messageError3 ;
	private String messageError4 ;
	
	private String user ;
	private String pass ;
	private TblGanador pais ;
	
	private int actualWorkAreaIndex ;
	private String actualWorkArea ;
        private int menuAct ;
        private int numAler ;
	
	private ArrayList< String > history = new ArrayList< String >( ) ;
	
	private boolean loggedIn ;
	
	private TblRole actualRole ;
	private TblCuenta actualCount ;
        private TblTipoCuenta countType ;
        private int idioma ;
	
	private TblUsuario userTO ;
        private TblGanador ganadorTo ;
	
	private UserTO newUser ;
	
	// manejo de cmapana
	private GenerarCampanaRegistrarForm manejadorCampana ;
	
	/**
	 * 	Recibe el usuario y la constrasenia sin encriptar.
	 * 
	 * @param user Usuario
	 * @param pass Contrasenia en texto claro.
	 */
	public UserLogin( String user , String pass )
	{
		this.user = user ;
		this.pass = pass ;
	}
	
	public boolean login( )
		throws
			MasterCardException
	{
		userTO = MasterCardDAO.checkUser( user , MCUtil.encryptPassword( pass ) ) ;
		
		// en caso de null
		if( userTO == null ) {
                    MasterCardDAO.closeEntityManager( ) ;
                    return false ;
                }
			
		
		List< TblRole > roles = userTO.getTblRoles( ) ;
		
		// cambia a true el loggedId
		loggedIn = true ;
                idioma = userTO.getIdioma( ) ;
		
                MasterCardDAO.closeEntityManager( ) ;
		// en caso de uqe si haya checado
		return true ;
			
	}
        
        public boolean loginGanador ( )
                throws
                        MasterCardException
        {
            // en caso de null
            if (user == null || pass == null) {
                return false;
            }
            
            ganadorTo = MasterCardDAO.checkGanador( user, pass ) ;
            MasterCardDAO.closeEntityManager( ) ;
            
            // encaso de null
            if ( ganadorTo == null )
                return false ;
            
            // cambia a true el loggedId
            loggedIn = true ;
            
            return true ;
        }
	
	public boolean logout( )
		throws
			MasterCardException
	{
		// cambia a true el loggedId
		loggedIn = false ;
		
		this.actualRole = null ;
		this.userTO = null ;
		this.actualCount = null ;
		this.actualRole = null ;
                this.countType = null ;
                this.idioma = -1 ;
		
		// vacia el historico
		history.clear( ) ;
		
		// en caso de uqe si haya checado
		return true ;
			
	}
	
	public List< TblRole > getUserRoles( )
	{
		if( userTO == null || ! loggedIn )
			return null ;
		
		ArrayList< TblRole > roles = new ArrayList< TblRole >( ) ;
		
		List< TblRole > userRoles = userTO.getTblRoles( ) ;
		
		// en caso de que este en null
		if( userRoles == null )
			return roles ;
		
		Iterator< TblRole > iter = userRoles.iterator( ) ;
		
		while( iter.hasNext( ) )
		{
			roles.add( iter.next( ) ) ;
		}
		
		// en caso de uqe no sea null
		return roles ;
	}
	
	public List< TblCuenta > getUserCounts( )
	{
		if( userTO == null || ! loggedIn )
			return null ;
		
		ArrayList< TblCuenta > cuentas = new ArrayList< TblCuenta >( ) ;
		
		List< TblCuenta > userCuentas = userTO.getTblCuentas( ) ;
		
		// en caso de que este en null
		if( userCuentas == null )
			return cuentas ;
		
		Iterator< TblCuenta > iter = userCuentas.iterator( ) ;
		
		while( iter.hasNext( ) )
		{
			cuentas.add( iter.next( ) ) ;
		}
		
		// en caso de uqe no sea null
		return cuentas ;
	}
	
	public List< TblNivel > getUserLevels( )
	{
		if( userTO == null || ! loggedIn )
			return null ;
		
		ArrayList< TblNivel > roles = new ArrayList< TblNivel >( ) ;
		
		List< TblNivel > userRoles = userTO.getTblNivels( ) ;
		
		// en caso de que este en null
		if( userRoles == null )
			return roles ;
		
		Iterator< TblNivel > iter = userRoles.iterator( ) ;
		
		while( iter.hasNext( ) )
		{
			roles.add( iter.next( ) ) ;
		}
		
		// en caso de uqe no sea null
		return roles ;
	}
	
	public boolean isLoggedIn( )
	{
		return loggedIn ;
	}
	
	public String getUserName( )
	{
		// en caso d eque este null
		if( userTO == null )
			return "" ;
		
		// en caos de que no este en null
		return userTO.getNombre( ) ;
	}
	
	public String getEmail( )
	{
		// en caso d eque este null
		if( userTO == null )
			return "" ;
		
		// en caos de que no este en null
		return userTO.getEmail( ) ;
	}
	
	public String getPaswd( )
	{
		// en caso d eque este null
		if( userTO == null )
			return "" ;
		
		// en caos de que no este en null
		return userTO.getPswd( ) ;
	}
	
	public void setActualRoleId( int id )
		throws
			MasterCardException
	{
		if( userTO == null || ! loggedIn )
			throw new MasterCardException( 
					MCUtil.messages.getString( "com.mastercard.assets.web.errors.modules.login.UserMustBeLoggedIn" , user ) , 
					MCUtil.MASTERCARD_ERROR_CODE_USERLOGIN_USER_MUST_BE_LOGGEDIN , 
					null ) ;
		
		List< TblRole > userRoles = userTO.getTblRoles( ) ;
		
		// en caso de que este en null
		if( userRoles == null )
			throw new MasterCardException( 
					MCUtil.messages.getString( "com.mastercard.assets.web.errors.modules.login.ThereIsNoExistThatRole" ) , 
					MCUtil.MASTERCARD_ERROR_CODE_USERLOGIN_USER_THERE_IS_NO_EXIST_THAT_ROLE , 
					null ) ;
		
		Iterator< TblRole > iter = userRoles.iterator( ) ;
		
		while( iter.hasNext( ) )
		{
			// toma el rol
			TblRole role = iter.next( ) ;
			
			// en csao de que sea el mismo id
			if( id == role.getCveRole( ) )
			{
				// asigna
				this.actualRole = role ;
			}
		}
		
	}
	
	public void setActualCountId( int id )
		throws
			MasterCardException
	{
		if( userTO == null || ! loggedIn )
			throw new MasterCardException( 
					MCUtil.messages.getString( "com.mastercard.assets.web.errors.modules.login.UserMustBeLoggedIn" , user ) , 
					MCUtil.MASTERCARD_ERROR_CODE_USERLOGIN_USER_MUST_BE_LOGGEDIN , 
					null ) ;
		
		List< TblCuenta > userCuentas = userTO.getTblCuentas( ) ;
		
		// en caso de que este en null
		if( userCuentas == null )
			throw new MasterCardException( 
					MCUtil.messages.getString( "com.mastercard.assets.web.errors.modules.login.ThereIsNoExistThatCount" ) , 
					MCUtil.MASTERCARD_ERROR_CODE_USERLOGIN_USER_THERE_IS_NO_EXIST_THAT_COUNT , 
					null ) ;
		
		Iterator< TblCuenta > iter = userCuentas.iterator( ) ;
		
		while( iter.hasNext( ) )
		{
			// toma el rol
			TblCuenta cuenta = iter.next( ) ;
			
			// en csao de que sea el mismo id
			if( id == cuenta.getCveCuenta( ) )
			{
				// asigna
				this.actualCount = cuenta ;
			}
		}
		
	}
        
        public void setCountType( TblTipoCuenta countType )
        {
            this.countType = countType ;
        }
        
        public void setIdioma( int idioma )
	{
            this.idioma = idioma ;
	}
	
	public void backWorkArea( int i )
	{
		actualWorkAreaIndex -= i ;
		
		if( actualWorkAreaIndex < 0 )
			actualWorkAreaIndex = 0 ;
	}
	
	public void forwardWorkArea( int i )
	{
		actualWorkAreaIndex += i ;
		
		int lastIndex = history.size( ) - 1 ;
		
		if( actualWorkAreaIndex > lastIndex )
			actualWorkAreaIndex = lastIndex ;
	}
	
	public void setNextWorkArea( String nextWorkArea )
	{
		// en caso de null
		if( nextWorkArea == null )
			// lo guarda vacio
			nextWorkArea = "" ;
		
		// en caso de que el indice actual no sea el ultimo
		if( actualWorkAreaIndex < history.size( ) - 1 )
		{
			// borra las paginas posteriores
			// paginas a ser borradas
			int pagesErased = history.size( ) - 1 - actualWorkAreaIndex ;
			int indexDrop = actualWorkAreaIndex + 1  ;
			for( int i = 0 ; i < pagesErased ; i++ )
				history.remove( indexDrop ) ;
		}
		
		// guarda la siguiente pagina
		history.add( nextWorkArea ) ;
		
		// actualiza el indice actual
		actualWorkAreaIndex = history.size( ) - 1 ;
	}
	
	public String getActualWorkArea( )
	{
		int lastIndex = history.size( ) - 1 ;
		
		if( actualWorkAreaIndex > lastIndex )
			actualWorkAreaIndex = lastIndex ;
		
		// en caso de que sea menor a 0
		if( actualWorkAreaIndex < 0 )
			actualWorkAreaIndex = 0 ;
		
		return history.get( actualWorkAreaIndex ) ;
	}

	public String getMessageError() {
		return messageError;
	}

	public void setMessageError(String messageError) {
		this.messageError = messageError;
	}

	public String getMessageError2() {
		return messageError2;
	}

	public void setMessageError2(String messageError2) {
		this.messageError2 = messageError2;
	}
	
	public void clearMessageError( )
	{
		this.messageError = "" ;
		this.messageError2 = "" ;
		this.messageError3 = "" ;
		this.messageError4 = "" ;
	}
	
	public String getActualRoleName( )
	{
		if( actualRole == null )
			return "" ;
		
		// en caso de uqe no sea null
		return actualRole.getNombre( ) ;
	}
	
	public String getActualCountName( )
	{
		if( actualCount == null )
			return "" ;
		
		// en caso de uqe no sea null
		return actualCount.getNombre( ) ;
	}
        
        public TblTipoCuenta getCountType( )
        {
            return countType ;
        }
        
        public int getIdioma( )
        {
            return idioma ;
        }
                
	public String getMessageError3() {
		return messageError3;
	}

	public void setMessageError3(String messageError3) {
		this.messageError3 = messageError3;
	}

	public String getMessageError4() {
		return messageError4;
	}

	public void setMessageError4(String messageError4) {
		this.messageError4 = messageError4;
	}
	
	public int getCveUsuario( )
	{
		if( userTO == null )
			return -1 ;
		
		return userTO.getCveUsuario( ) ;
	}
	
	/**
	 * 	Regresa alertas no leidas del usuario
	 * 
	 * 	@return
	 */
	public List< TblAlertaUsuario > getAllNotReadedAlerts( )
	{
		if( userTO == null )
			return new java.util.ArrayList< TblAlertaUsuario >( ) ;
		
		// resultado
		java.util.ArrayList< TblAlertaUsuario > res = new java.util.ArrayList< TblAlertaUsuario >( ) ;
		
		// en caso de que no este en null
		List< TblAlertaUsuario > l = userTO.getTblAlertaUsuarios( ) ;
		
		int total = 0 ;
		
		// las recorre
		for( TblAlertaUsuario alert : l )
			// en caso de que sea 1
			if( alert.getLeida( ) == 1 )
				res.add( alert ) ;
		
		return res ;
	}
	
	/**
	 * 	Regresa alertas leidas del usuario
	 * 
	 * 	@return
	 */
	public List< TblAlertaUsuario > getAllReadedAlerts( )
	{
		if( userTO == null )
			return new java.util.ArrayList< TblAlertaUsuario >( ) ;
		
		// resultado
		java.util.ArrayList< TblAlertaUsuario > res = new java.util.ArrayList< TblAlertaUsuario >( ) ;
		
		// en caso de que no este en null
		List< TblAlertaUsuario > l = userTO.getTblAlertaUsuarios( ) ;
		
		int total = 0 ;
		
		// las recorre
		for( TblAlertaUsuario alert : l )
			// en caso de que sea 1
			if( alert.getLeida( ) == 2 )
				res.add( alert ) ;
		
		return res ;
	}
	
	/**
	 * 	Regresa todas las alertas del usuario
	 * 
	 * 	@return
	 */
	public List< TblAlertaUsuario > getAllAlerts( )
	{
		if( userTO == null )
			return new java.util.ArrayList< TblAlertaUsuario >( ) ;
		
		// resultado
		java.util.ArrayList< TblAlertaUsuario > res = new java.util.ArrayList< TblAlertaUsuario >( ) ;
		
		// en caso de que no este en null
		List< TblAlertaUsuario > l = userTO.getTblAlertaUsuarios( ) ;
		
		int total = 0 ;
		
		// las recorre
		for( TblAlertaUsuario alert : l )
			res.add( alert ) ;
		
		return res ;
	}
	
	public Integer getNumberOfAlertsNotReaded( )
	{
		if( userTO == null )
			return 0 ;
		
		try
		{
//			MasterCardDAO.refresh( userTO ) ;
			
			// en caso de que no este en null
			List< TblAlertaUsuario > l = userTO.getTblAlertaUsuarios( ) ;
			
			int total = 0 ;
			
			// las recorre
			for( TblAlertaUsuario alert : l )
				// en caso de que sea 1
				if( alert.getLeida( ) == 1 && alert.getStatus( ) == 1 )
					total++ ;
			
			return new Integer( total ) ;
		}catch( Exception e )
		{
			return new Integer( 0 ) ;
		}
	}
	
	public List< TblAlertaUsuario > getAlertsNotReaded( )
	{
		if( userTO == null )
			return new ArrayList< TblAlertaUsuario >( ) ;
		
		// en caso de que no este en null
		List< TblAlertaUsuario > l = userTO.getTblAlertaUsuarios( ) ;
		List< TblAlertaUsuario > res = new ArrayList< TblAlertaUsuario >( ) ;
		
		int total = 0 ;
		
		// las recorre
		for( TblAlertaUsuario alert : l )
			// en caso de que sea no este leida y que este activa
			if( alert.getLeida( ) == 1 && alert.getStatus( ) == 1 )
				res.add( alert ) ;
		
		return res ;
	}
	
	public List< TblAlertaUsuario > getAlertsReaded( )
	{
		if( userTO == null )
			return new ArrayList< TblAlertaUsuario >( ) ;
		
		// en caso de que no este en null
		List< TblAlertaUsuario > l = userTO.getTblAlertaUsuarios( ) ;
		List< TblAlertaUsuario > res = new ArrayList< TblAlertaUsuario >( ) ;
		
		int total = 0 ;
		
		// las recorre
		for( TblAlertaUsuario alert : l )
			// en caso de que sea no este leida y que este activa
			if( alert.getLeida( ) == 2 && alert.getStatus( ) == 1 )
				res.add( alert ) ;
		
		return res ;
	}
	
	public String getLogin( )
	{
		if( userTO == null )
			return "" ;
		
		return userTO.getLogin( ) ;
	}

	public UserTO getNewUser() {
		return newUser;
	}

	public void setNewUser(UserTO newUser) {
		this.newUser = newUser;
	}
	
	public List< TblTipoCuentaPaquete > getTipoCuentaPaquetes( )
	{
		// toma el tipo de cuenta al que pertenece
//		TblTipoCuenta tipoCuenta = userTO.getT
		return null ;
	}
	
	public TblTipoCuenta getActualCountType( )
	{
		System.out.println( "UserLogin count : " + actualCount ) ;
		
		if( actualCount == null )
			return null ;
		
		return actualCount.getTblTipoCuenta( ) ;
	}
	
	public int getActualRoleId( )
	{
		if( actualRole == null )
			return -1 ;
		
		return actualRole.getCveRole( ) ;
	}
	
	public int getActualCountId( )
	{
		if( actualCount == null )
			return -1 ;

		return actualCount.getCveCuenta( ) ;
	}
	
	public TblUsuario getTblUsuario( )
	{
		return userTO ;
	}
        
        public TblGanador getTblGanador( )
	{
		return ganadorTo ;
	}
	
	/**
	 * 	Regresa las cuentas hermanas en caso de que el tipo de cuenta sea NKA
	 */
	public List< TblCuenta > getBindCounts( )
	{
		// resultado
		List< TblCuenta > cuentas = new ArrayList< TblCuenta >( ) ;
		
		// toma las cuentas del tipo de cuenta
		TblTipoCuenta tipoCuenta = this.actualCount.getTblTipoCuenta( ) ;
		List< TblCuenta > cuentasHijas = tipoCuenta.getTblCuentas( ) ;
		
		// en caso de que solamente sea una
		if( cuentasHijas.size( ) < 2 )
			return cuentas ;
		
		int cveCuenta = this.actualCount.getCveCuenta( ) ;
		
		// recorre las cuentas
		for( TblCuenta cuenta : cuentasHijas )
		{
			// en caso de estado = 0
			if( cuenta.getStatus( ) == 0 )
				// siguiente
				continue ;
			
			// en caso d eque sea diferente a la cuenta actual
			if( cuenta.getCveCuenta( ) != cveCuenta )
				// agrega
				cuentas.add( cuenta ) ;
		}
		
		return cuentas ;
	}

	public GenerarCampanaRegistrarForm getManejadorCampana() {
		return manejadorCampana;
	}

	public void setManejadorCampana(GenerarCampanaRegistrarForm manejadorCampana) {
		this.manejadorCampana = manejadorCampana;
	}

	public boolean haveLevel( int cveNivel )
	{
		// toma los niveles
		List< TblNivel > niveles = userTO.getTblNivels( ) ;
		
		// recorre los niveles
		for( TblNivel nivel : niveles )
		{
			// en caos de que coincida
			if( nivel.getCveNivel( ) == cveNivel )
				// regresa true
				return true ;
		}
		
		// en caso de qwue ninguno coincida
		return false ;
	}
	
	
	public Object getAttribute( String attribute )
	{
		return attributes.get( attribute ) ;
	}
	
	public void setAttribute( String attribute , Object value )
	{
		attributes.put( attribute , value ) ;
	}
	
	public Enumeration< String > getAttributeNames( )
	{
		return attributes.keys( ) ;
	}
	
	public void remvoeAttribute( String key )
	{
		attributes.remove( key ) ;
	}

    /**
     * @return the menuAct
     */
    public int getMenuAct() {
        return menuAct;
    }

    /**
     * @param menuAct the menuAct to set
     */
    public void setMenuAct(int menuAct) {
        this.menuAct = menuAct;
    }
    
    /**
     * @return the numAler
     */
    public int getNumAler() {
        return numAler;
    }

    /**
     * @param numAler the menuAct to set
     */
    public void setNumAler(int numAler) {
        this.numAler = numAler;
    }
    
}
